﻿using System;
using System.Linq;
using System.Runtime.InteropServices;
using System.Diagnostics;

namespace InnovTech.Util
{

    /// <summary>
    /// © SICAT 2012
    /// \contact han
    /// </summary>
    public static class ProcessUtil
    {

        #region Fields

        /*
        const int SW_HIDE = 0;
        const int SW_SHOWNORMAL = 1;
        const int SW_SHOWMINIMIZED = 2;
        const int SW_SHOWMAXIMIZED = 3;
        const int SW_SHOWNOACTIVATE = 4;
        const int SW_RESTORE = 9;
        const int SW_SHOWDEFAULT = 10;
        */
        const int swRestore = 9;

        #endregion


        #region Properties

        #endregion


        #region Constructors

        

        #endregion


        #region Methods

        public static DateTime GetProcessStartTime(string processName)
        {
            Process proc = null;
            if (ProcessUtil.TryGetProcess(processName, out proc))
            {
                return proc.StartTime;
            }
            return default(DateTime);
        }

        public static bool SetProcessFocus(string processName)
        {
            Process proc = null;
            if (TryGetProcess(processName, out proc))
            {
                return SetProcessFocus(proc);
            }
            return false;
        }

        public static bool SetProcessFocus(Process proc)
        {
            if (proc == null) return false;
            IntPtr hWnd = proc.MainWindowHandle;
            if (IsIconic(hWnd))
                ShowWindowAsync(hWnd, swRestore);

            return SetForegroundWindow(hWnd);
        }

        public static Process GetProcess(string name)
        {
            var q = from proc in Process.GetProcesses()
                    where proc.ProcessName.Contains(name)
                    select proc;
            return q.Any() ? q.First() : null;
        }

        public static bool TryGetProcess(string name, out Process proc)
        {
            proc = GetProcess(name);
            return proc != null;
        }

        #region native

        /// <summary>
        /// Moves a window to the foreground
        /// </summary>
        /// <param name="hWnd"></param>
        /// <returns></returns>
        [DllImport("user32.dll")]
        static extern bool SetForegroundWindow(IntPtr hWnd);

        /// <summary>
        /// Sets the focus on the given window 
        /// </summary>
        /// <param name="hWnd"></param>
        /// <returns></returns>
        [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
        public static extern IntPtr SetFocus(HandleRef hWnd);

        /// <summary>
        /// Shows the given window asynchronous.
        /// </summary>
        /// <param name="hWnd"></param>
        /// <param name="nCmdShow"></param>
        /// <returns></returns>
        [DllImport("user32.dll")]
        private static extern
        bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);

        /// <summary>
        /// Checks whether the given window is minimized.
        /// </summary>
        /// <param name="hWnd"></param>
        /// <returns></returns>
        [DllImport("user32.dll")]
        private static extern
        bool IsIconic(IntPtr hWnd);

        #endregion 

        #endregion

    }
}
